package com.brzjomo.secretiveworld.world.gen.feature.structure.abandoned.house;

import java.util.Random;
import java.util.function.Function;

import com.brzjomo.secretiveworld.SecretiveWorld;
import com.mojang.datafixers.Dynamic;

import net.minecraft.util.Rotation;
import net.minecraft.util.SharedSeedRandom;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeManager;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.feature.structure.StructureStart;
import net.minecraft.world.gen.feature.template.TemplateManager;

public class AbandonedHouseStructure extends Structure<AbandonedHouseConfig> {

	public AbandonedHouseStructure(Function<Dynamic<?>, ? extends AbandonedHouseConfig> configFactoryIn) {
		super(configFactoryIn);
	}
	
	@Override
	public boolean canBeGenerated(BiomeManager biomeManagerIn, ChunkGenerator<?> generatorIn, Random randIn, int chunkX,
			int chunkZ, Biome biomeIn) {
		((SharedSeedRandom)randIn).setLargeFeatureSeedWithSalt(generatorIn.getSeed(), chunkX, chunkZ, this.getSeedModifier());
		if (generatorIn.hasStructure(biomeIn, this)) {
			AbandonedHouseConfig structureConfig = (AbandonedHouseConfig) generatorIn.getStructureConfig(biomeIn,
					this);
			double d0 = structureConfig.probability;
			return randIn.nextDouble() < d0;
		} else {
			return false;
		}
	}

	@Override
	public IStartFactory getStartFactory() {
		return AbandonedHouseStructure.Start::new;
	}

	@Override
	public String getStructureName() {
		return SecretiveWorld.MODID + ":Abandoned_House";
	}

	@Override
	public int getSize() {
		return 3;
	}

	protected int getSeedModifier() {
		Random rand = new Random();
		return rand.nextInt();
	}

	@Override
	protected ChunkPos getStartPositionForPosition(ChunkGenerator<?> chunkGenerator, Random random, int x, int z, int spacingOffsetsX, int spacingOffsetsZ) {
	      int i = chunkGenerator.getSettings().getMansionDistance();
	      int j = chunkGenerator.getSettings().getMansionSeparation();
	      int k = x + i * spacingOffsetsX;
	      int l = z + i * spacingOffsetsZ;
	      int i1 = k < 0 ? k - i + 1 : k;
	      int j1 = l < 0 ? l - i + 1 : l;
	      int k1 = i1 / i;
	      int l1 = j1 / i;
	      ((SharedSeedRandom)random).setLargeFeatureSeedWithSalt(chunkGenerator.getSeed(), k1, l1, this.getSeedModifier());
	      k1 = k1 * i;
	      l1 = l1 * i;
	      k1 = k1 + (random.nextInt(i - j) + random.nextInt(i - j)) / 2;
	      l1 = l1 + (random.nextInt(i - j) + random.nextInt(i - j)) / 2;
	      return new ChunkPos(k1, l1);
	   }

	public static class Start extends StructureStart {

		public Start(Structure<?> structure, int chunkX, int chunkZ, MutableBoundingBox boundingBox, int reference,
				long seed) {
			super(structure, chunkX, chunkZ, boundingBox, reference, seed);
		}

		@Override
		public void init(ChunkGenerator<?> generator, TemplateManager templateManagerIn, int chunkX, int chunkZ,
				Biome biomeIn) {
			Random randz = new Random();
			Rotation rotation;
			
			switch(randz.nextInt(3)) {
			case 0:
				rotation = Rotation.NONE;
				break;
			case 1:
				rotation = Rotation.CLOCKWISE_90;
				break;
			case 2:
				rotation = Rotation.CLOCKWISE_180;
				break;
			case 3:
				rotation = Rotation.COUNTERCLOCKWISE_90;
				break;
			default:
				rotation = Rotation.NONE;
				break;
			}
			
			int x = (chunkX << 4) + 7;
			int z = (chunkZ << 4) + 7;
			int y = generator.getNoiseHeightMinusOne(x, z, Heightmap.Type.WORLD_SURFACE_WG);
			BlockPos pos = new BlockPos(x, y - 4, z);

			AbandonedHousePiece.start(templateManagerIn, pos, rotation, this.components, this.rand);

			this.recalculateStructureSize();

			SecretiveWorld.LOGGER.info("abandoned_house: " + pos + "rot: " + rotation);
		}
	}

}
